/*
 * Copyright (c) 2024-2025 LTC-CN. All rights reserved.
 * <p>
 * This file is part of the ltc-cn-springboot project.
 * <p>
 * ltc-cn-springboot is distributed under the terms of the MIT License.
 * For details, see the accompanying LICENSE file or visit:
 * <a href="https://www.ltc-cn.top/projects">...</a>
 */

package top.ltc_cn.minecraft_manager.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.ltc_cn.minecraft_manager.properties.HttpProperties;

@Configuration
@Slf4j
public class HttpsConfiguration {

    @Autowired
    private HttpProperties httpProperties;
    @Autowired
    private ServerProperties serverProperties;

    @Bean
    public TomcatServletWebServerFactory servletContainer() {
        log.info("正在读取/设置HTTP配置");

        // 获取springboot设置的http端口
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                if (httpProperties.isEnableHttps()) {
                    SecurityConstraint constraint = new SecurityConstraint();
                    constraint.setUserConstraint("CONFIDENTIAL");
                    SecurityCollection collection = new SecurityCollection();
                    collection.addPattern("/*");
                    constraint.addCollection(collection);
                    context.addConstraint(constraint);
                }
            }
        };

        if (httpProperties == null) {
            log.error("httpProperties 为空");
            throw new IllegalStateException("httpProperties 不能为空");
        }

        Integer httpPort = httpProperties.getHttpPort();
        if (httpPort != null) {
            log.debug("重新设置Tomcat HTTP端口：{}", httpPort);
            try {
                tomcat.setPort(httpPort);
            } catch (Exception e) {
                log.error("设置HTTP端口失败", e);
                // 根据需求决定是否抛出异常或继续执行
            }
        } else {
            log.warn("httpPort 为null，使用默认Tomcat端口：{}", tomcat.getPort());
            httpProperties.setHttpPort(tomcat.getPort());
        }

        if (!httpProperties.isEnableHttps()) {
            log.info("HTTPS未启用");
            return tomcat;
        }

        Integer httpsPort = httpProperties.getHttpsPort();
        if (httpsPort != null) {
            log.debug("重新设置Tomcat HTTPS端口：{}", httpsPort);
            try {
                tomcat.setPort(httpsPort);
            } catch (Exception e) {
                log.error("设置HTTPS端口失败", e);
                // 根据需求决定是否抛出异常或继续执行
            }
        } else {
            log.warn("httpsPort 为null，未设置HTTPS端口");
        }


        try {
            Connector connector = httpConnector();
            if (connector != null) {
                tomcat.addAdditionalTomcatConnectors(connector);
            }
            return tomcat;
        } catch (Exception e) {
            log.error("创建Connector失败", e);
            throw new IllegalStateException("创建Connector失败", e);
        }
    }

    /**
     * 强制将所有的http请求转发到https
     * @return httpConnector
     */
    @Bean
    public Connector httpConnector() {
        // 获取springboot设置的http端口
        Integer httpsPort = httpProperties.getHttpsPort();
        Integer httpPort = httpProperties.getHttpPort();

        if (httpsPort == null) {
            log.error("HTTPS端口配置无效");
            throw new IllegalStateException("HTTPS端口配置无效");
        }

        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");

        if (!httpProperties.isEnableHttps()) {
            log.info("Http请求转发到Https未启用");
            if (serverProperties.getSsl().isEnabled()) {
                log.error("SSL配置设置为开启状态，当前未启动HTTPS，请关闭SSL");
                throw new IllegalStateException("SSL配置设置为开启状态，当前未启动HTTPS，请关闭SSL");
            }
            return null;
        } else if (httpProperties.isOnlyHttps()) {
            log.info("Https已启用");
            return null;
        } else {
            log.info("Http请求并存Https已启用 (不稳定，推荐打开onlyHttps)");
            if (!serverProperties.getSsl().isEnabled()) {
                log.error("SSL配置未设置为开启状态，无法启用HTTPS");
                throw new IllegalStateException("SSL配置未设置为开启状态，无法启用HTTPS");
            }
            connector.setScheme("http");
            connector.setPort(httpPort);
            log.debug("http端口号：{}", httpPort);
            log.debug("https端口号：{}", httpsPort);
            connector.setSecure(false);
            connector.setRedirectPort(httpsPort);
            return connector;
        }
    }
}